package org.hackystat.sdsa.analyzer.model.activity.refactoring;

import java.util.HashMap;
import java.util.Map;

/**
 * Defines refactor operators.
 * 
 * @author Hongbing Kou
 */
public class RefactorOperator {
  /** Operation enumerator. */
  public enum Operator { ADD, REMOVE, MOVE, RENAME, UNKNOWN };
  
  /** Operator name*/
  private final Operator op;
  /** A map containing single instance. */
  private static Map<String, RefactorOperator> operatorMap; 
  
  static  {
    operatorMap = new HashMap<String, RefactorOperator>();
    for (Operator op : Operator.values()) {
      operatorMap.put(op.name(), new RefactorOperator(op));
    }
  }
  
  /** 
   * Instantiates an operator.
   * 
   * @param name Operator name. 
   */
  private RefactorOperator(Operator name) {
    this.op = name;
  }

  
  /**
   * Gets the operator name
   * 
   * @return Refactor operator.
   */
  public String getName() {
    return this.op.name();
  }
  
  /**
   * Gets predefined refactor operator with name.
   * 
   * @param name Refactor operator name.
   * @return Refactor operator instance.
   */
  public static RefactorOperator getInstance(String name) {
    String upperName = name.toUpperCase();
    if (operatorMap.containsKey(upperName)) {
      return operatorMap.get(upperName);
    }
    else {
      return operatorMap.get(Operator.UNKNOWN.name());
    }
  }


  /**
   * Checks whether this operation is unary operation.
   * 
   * @return True if it is ADD/REMOVE.
   */
  public boolean isUnary() {
    return this.op == Operator.ADD || this.op == Operator.REMOVE;
  }


  /**
   * Checks whether this operation is binary type.
   * 
   * @return True if it is RENAME/MOVE.
   */
  public boolean isBinary() {
    return this.op == Operator.MOVE || this.op == Operator.RENAME;
  }
  
  /**
   * Gets string representation of refactoring operator.
   * 
   * @return Refactor operator.
   */
  @Override public String toString() {
    return this.op.name();
  }
}